package org.dealpdf.sample;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.List;

/**
 * 导出出库单
 * 1、无模版、动态内容生成
 * 图片嵌入和动态表格渲染
 */
public class ExportOutBondOrder {

    public static void main(String[] args) {
        try {
            // 创建文档
            Document document = new Document(PageSize.A4);
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("outbound_document.pdf"));
            document.open();

            // 1. 左上角添加 logo
            addLogo(document, writer);

            // 2. 添加可见标题
            addDocumentTitle(document);

            // 3. 基础单据信息 (向下移动，4列布局)
            addBasicInfo(document);

            // 4. 出库单明细信息 (动态表格)
            addOutboundDetails(document);

            // 5. 二维码区域 (右上角)
            addQRCodePlaceholder(document, writer);

            // 6. 添加水印
            addTextWatermark(writer, "ikun");

            document.close();
            System.out.println("PDF 生成成功！文件位置: outbound_document.pdf");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void addDocumentTitle(Document document) throws DocumentException, IOException {
        BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        Font titleFont = new Font(bfChinese, 20, Font.BOLD);
        Paragraph title = new Paragraph("出库单", titleFont);
        title.setAlignment(Element.ALIGN_CENTER);
//        title.setSpacingBefore(5f);
//        title.setSpacingAfter(5f);
        document.add(title);
    }

    // 添加左上角 logo
    private static void addLogo(Document document, PdfWriter writer) throws DocumentException, IOException {
        // 替换为实际 logo 图片路径，例如 "src/main/resources/logo.jpeg"
        Image logo = Image.getInstance("src/main/resources/logo.jpeg");
        logo.scaleToFit(100, 100); // 调整 logo 大小

        logo.setAlignment(Image.ALIGN_LEFT);
        document.add(logo); // 使用文档流插入

    }

    // 添加基础单据信息 (4列布局，增加间距)
    private static void addBasicInfo(Document document) throws DocumentException, IOException {
        PdfPTable table = new PdfPTable(4);
        table.setWidthPercentage(100);
        table.setSpacingBefore(50f);
        table.setSpacingAfter(50f);

        BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        Font headerFont = new Font(bfChinese, 14, Font.BOLD);
        Font contentFont = new Font(bfChinese, 14);

        Map<String, String> apiData = getBaseInfoFromApi();

        List<String> keys = new ArrayList<>(fieldNameToLabelMap.keySet());
        for (int i = 0; i < keys.size(); i += 2) {
            String key1 = keys.get(i);
            String key2 = (i + 1 < keys.size()) ? keys.get(i + 1) : "";

            String label1 = fieldNameToLabelMap.get(key1);
            String value1 = apiData.getOrDefault(key1, "");

            String label2 = key2.isEmpty() ? "" : fieldNameToLabelMap.get(key2);
            String value2 = key2.isEmpty() ? "" : apiData.getOrDefault(key2, "");

            addInfoRow(table, label1, value1, label2, value2, headerFont, contentFont);
        }

        document.add(table);
    }

    // 工具方法：添加单行 (4列)
    private static void addInfoRow(PdfPTable table, String key1, String value1, String key2, String value2, Font keyFont, Font valueFont) {
        PdfPCell keyCell1 = new PdfPCell(new Phrase(key1, keyFont));
        keyCell1.setHorizontalAlignment(Element.ALIGN_LEFT);
        keyCell1.setBorderWidth(0.5f);
        keyCell1.setPadding(10f);
        keyCell1.setMinimumHeight(25f);

        PdfPCell valueCell1 = new PdfPCell(new Phrase(value1, valueFont));
        valueCell1.setHorizontalAlignment(Element.ALIGN_LEFT);
        valueCell1.setBorderWidth(0.5f);
        valueCell1.setPadding(10f);
        valueCell1.setMinimumHeight(25f);

        PdfPCell keyCell2 = new PdfPCell(new Phrase(key2, keyFont));
        keyCell2.setHorizontalAlignment(Element.ALIGN_LEFT);
        keyCell2.setBorderWidth(0.5f);
        keyCell2.setPadding(10f);
        keyCell2.setMinimumHeight(25f);

        PdfPCell valueCell2 = new PdfPCell(new Phrase(value2, valueFont));
        valueCell2.setHorizontalAlignment(Element.ALIGN_LEFT);
        valueCell2.setBorderWidth(0.5f);
        valueCell2.setPadding(10f);
        valueCell2.setMinimumHeight(25f);

        table.addCell(keyCell1);
        table.addCell(valueCell1);
        table.addCell(keyCell2);
        table.addCell(valueCell2);
    }

    // 添加动态出库单明细信息
    private static void addOutboundDetails(Document document) throws DocumentException, IOException {
        // 模拟从接口获取的动态数据
        List<OutboundDetail> details = generateSampleDetails();

        // 创建表格 (7列: 序号, 订单号, 订单明细号, 产品名称, 单位, 数量, 单价)
        PdfPTable table = new PdfPTable(7);
        table.setWidthPercentage(100);
        table.setSpacingBefore(50f); // 增加间距，向下移动以避免被上部内容覆盖

        // 使用支持中文的字体
        BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        Font headerFont = new Font(bfChinese, 12, Font.BOLD);
        Font contentFont = new Font(bfChinese, 12);

        // 表头
        addTableHeader(table, headerFont);

        // 动态添加数据
        for (int i = 0; i < details.size(); i++) {
            OutboundDetail detail = details.get(i);
            table.addCell(createCell(String.valueOf(i + 1), contentFont));
            table.addCell(createCell(detail.getOrderId(), contentFont));
            table.addCell(createCell(detail.getDetailId(), contentFont));
            table.addCell(createCell(detail.getProductName(), contentFont));
            table.addCell(createCell(detail.getUnit(), contentFont));
            table.addCell(createCell(String.valueOf(detail.getQuantity()), contentFont));
            table.addCell(createCell(String.format("%.2f", detail.getUnitPrice()), contentFont));
        }

        document.add(table);
    }

    // 模拟出库单明细数据 (动态获取的示例)
    private static List<OutboundDetail> generateSampleDetails() {
        List<OutboundDetail> details = new ArrayList<>();
        details.add(new OutboundDetail("BF-03-05-1", "no1", "34CrNiMo6", "原材料", 6.60, 100.00));
        details.add(new OutboundDetail("BF-03-05-2", "no2", "35CrMo", "半成品", 5.5, 120.00));
        details.add(new OutboundDetail("BF-03-05-3", "no3", "Q235", "成品", 10.0, 80.00));
        return details;
    }

    // 添加表格表头
    private static void addTableHeader(PdfPTable table, Font font) {
        String[] headers = {"序号", "订单号", "订单明细号", "产品名称", "单位", "数量", "单价"};
        for (String header : headers) {
            PdfPCell cell = new PdfPCell(new Phrase(header, font));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
            cell.setMinimumHeight(25f);
            table.addCell(cell);
        }
    }

    // 创建单元格
    private static PdfPCell createCell(String content, Font font) {
        PdfPCell cell = new PdfPCell(new Phrase(content, font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setBorderWidth(0.5f);
        cell.setMinimumHeight(25f);
        cell.setPadding(8f);
        return cell;
    }

    // 添加二维码 (右上角)
    private static void addQRCodePlaceholder(Document document, PdfWriter writer) throws DocumentException {
        try {
            // 获取第一个订单信息作为二维码内容
            List<OutboundDetail> details = generateSampleDetails();
            if (!details.isEmpty()) {
                OutboundDetail detail = details.get(0);
                String qrContent = "OrderID: " + detail.getOrderId() + "\nUnitPrice: " + detail.getUnitPrice() +
                        "\nQuantity: " + detail.getQuantity() + "\nDate: 2025-07-10";

                // 生成二维码图像
                int size = 100;
                BitMatrix bitMatrix = new MultiFormatWriter().encode(qrContent, BarcodeFormat.QR_CODE, size, size);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                MatrixToImageWriter.writeToStream(bitMatrix, "png", baos);
                Image qrImage = Image.getInstance(baos.toByteArray());
                qrImage.scaleToFit(size, size);

                // 设置二维码位置 —— 保持原有位置
                float x = PageSize.A4.getWidth() - size - 10f;
                float y = PageSize.A4.getHeight() - qrImage.getScaledHeight() - 10f;
                qrImage.setAbsolutePosition(x, y);

                writer.getDirectContent().addImage(qrImage);
            } else {
                Paragraph qr = new Paragraph();
                qr.add(new Chunk("二维码区域 (无数据)\n", FontFactory.getFont(FontFactory.HELVETICA, 14, Font.BOLD)));
                qr.setAlignment(Element.ALIGN_RIGHT);
                document.add(qr);
            }
        } catch (Exception e) {
            e.printStackTrace();
            Paragraph qr = new Paragraph();
            qr.add(new Chunk("二维码区域 (生成失败)\n", FontFactory.getFont(FontFactory.HELVETICA, 14, Font.BOLD)));
            qr.setAlignment(Element.ALIGN_RIGHT);
            document.add(qr);
        }
    }

    // 出库单明细的简单数据类
    static class OutboundDetail {
        private String orderId;
        private String detailId;
        private String productName;
        private String unit;
        private double quantity;
        private double unitPrice;

        public OutboundDetail(String orderId, String detailId, String productName, String unit, double quantity, double unitPrice) {
            this.orderId = orderId;
            this.detailId = detailId;
            this.productName = productName;
            this.unit = unit;
            this.quantity = quantity;
            this.unitPrice = unitPrice;
        }

        public String getOrderId() { return orderId; }
        public String getDetailId() { return detailId; }
        public String getProductName() { return productName; }
        public String getUnit() { return unit; }
        public double getQuantity() { return quantity; }
        public double getUnitPrice() { return unitPrice; }
    }

    private static void addTextWatermark(PdfWriter writer, String watermarkText) throws IOException, DocumentException {
        PdfContentByte under = writer.getDirectContentUnder();

        // 设置字体
        BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        under.saveState();

        // 设置透明度
        PdfGState gs1 = new PdfGState();
        gs1.setFillOpacity(0.1f); // 越小越淡
        under.setGState(gs1);

        // 设置字体大小和颜色
        under.beginText();
        under.setFontAndSize(baseFont, 60); // 字体大小
        under.setColorFill(BaseColor.LIGHT_GRAY);

        // 页面宽高
        float pageWidth = PageSize.A4.getWidth();
        float pageHeight = PageSize.A4.getHeight();

        // 网格循环：每隔一定间距绘制一行水印（x 横向，y 纵向）
        for (float x = -100; x < pageWidth + 100; x += 200) {
            for (float y = -100; y < pageHeight + 100; y += 150) {
                under.showTextAligned(Element.ALIGN_CENTER, watermarkText, x, y, 45); // 倾斜 45 度
            }
        }

        under.endText();
        under.restoreState();
    }

    private static final Map<String, String> fieldNameToLabelMap = new LinkedHashMap<>();

    static {
        fieldNameToLabelMap.put("orderCode", "单据编号");
        fieldNameToLabelMap.put("outboundDate", "出库日期");
        fieldNameToLabelMap.put("customerName", "客户名称");
        fieldNameToLabelMap.put("warehouseCode", "仓库编号");
        fieldNameToLabelMap.put("creator", "制单人");
        fieldNameToLabelMap.put("auditor", "审核人");
        fieldNameToLabelMap.put("createTime", "制单时间");
        fieldNameToLabelMap.put("outboundOrderId", "出库单据ID");
    }
    private static Map<String, String> getBaseInfoFromApi() {
        Map<String, String> data = new HashMap<>();
        data.put("orderCode", "BF-03-05-1");
        data.put("outboundDate", "2025-06-04");
        data.put("customerName", "某某公司");
        data.put("warehouseCode", "CK_7525080416537318");
        data.put("creator", "张三");
        data.put("auditor", "李四");
        data.put("createTime", "2025-06-04 16:15:48");
        data.put("outboundOrderId", "13500135000");
        return data;
    }
}